package edu.nf.ch09.websocket;

import edu.nf.ch09.common.MessageUtils;
import edu.nf.ch09.vo.Chat;
import edu.nf.ch09.vo.Online;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wangl
 * @date 2025/9/18
 * 聊天室服务端
 * configurator属性设置握手处理器
 */
@Component
@ServerEndpoint(value = "/connect",
        configurator = HandshakeHandler.class)
public class ChatServer {

    /**
     * 使用map集合维护一个用户列表
     * key是连接session的id
     * value是客户端的session对象
     */
    private static final Map<String,Session> users = new HashMap<>();

    /**
     * 用户上线
     * 每当由用户连接时，创建的session就保存到用户列表中
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) throws IOException {
        //获取用户信息
        String user = (String) session.getUserProperties().get("user");
        users.put(user, session);
        //通知用户
        notifyUser();
    }

    /**
     * 接收客户端发送的消息并执行群发（发送给所有的session）
     * @param session
     * @param message
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        //获取发送人
        String user = (String) session.getUserProperties().get("user");
        //构建消息
        Chat chat = new  Chat();
        //发送人
        chat.setSendUser(user);
        //发送时间
        String sendDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
        chat.setSendDate(sendDate);
        //消息内容
        chat.setContent(message);
        String json = MessageUtils.createMessage(chat);
        //群发
        sendAllUser(json);
    }

    /**
     * 用户离线
     * 离线时，将从用户列表移除当前的session
     * @param session
     */
    @OnClose
    public void onClose(Session session) throws IOException {
        //获取用户信息
        String user = (String) session.getUserProperties().get("user");
        users.remove(user);
        //通知用户
        notifyUser();
    }
    /**
     * 群发
     * @param message
     */
    private void sendAllUser(String message) {
        users.forEach((id,session)->{
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                throw new RuntimeException("发送失败", e);
            }
        });
    }

    /**
     * 通知用户在线人数
     * @throws IOException
     */
    private void notifyUser() throws IOException {
        Online online = new Online();
        online.setTotal(users.size());
        String json = MessageUtils.createMessage(online);
        sendAllUser(json);
    }
}